package com.easycode.devtool.util;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.reflect.TypeToken;
import com.google.gson.*;
import com.google.gson.stream.JsonReader;

import javax.servlet.http.HttpServletRequest;
import java.io.CharArrayReader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2015/7/1.
 */
public class JsonUtils {


    /**
     * 获取任意对象的属性对应的JSON字符串
     *
     * @param object
     * @return
     */
    public static String getJson(Object object) {
        return new Gson().toJson(object);
    }



    public static String getJsonDisableHtmlEscaping(Object object) {
        GsonBuilder gsonBuilder = new GsonBuilder().registerTypeAdapter(Double.class, new JsonSerializer<Double>() {
            @Override
            public void serialize(Double src, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
//                if(src == src.longValue())
//                    return new JsonPrimitive(src.longValue()); todo
//                return new JsonPrimitive(src);
            }

//            @Override
//            public JsonElement serialize(Double src, Type type, JsonSerializationContext jsonSerializationContext) {
//                if(src == src.longValue())
//                    return new JsonPrimitive(src.longValue());
//                return new JsonPrimitive(src);
//            }
        });
//        .setPrettyPrinting()
        gsonBuilder.disableHtmlEscaping();
        return gsonBuilder.create().toJson(object);
    }




    /**
     * 获取任意对象的属性对应的JSON字符串
     *
     * @param map
     * @return
     */
    public static String getJson(Map<String, Object> map) {
        return new Gson().toJson(map);
    }

    /**
     * 将JSON格式字符串转为map对象
     *
     * @param json
     * @return
     */
    public static HashMap<String, String> getMapDataFromJson(String json) {
        HashMap<String, String> map = new HashMap<String, String>();

        if (!StringUtils.isEmpty(json)) {
            Gson gson = new Gson();
            try {
                map = gson.fromJson(json, new TypeToken<HashMap<String, String>>() {
                }.getType());
            } catch (Exception e) {
                //System.out.println(e.getMessage());
            }
        }
        return map;
    }

//    /**
//     * 得到忽略大小写的哈希表细心
//     *
//     * @param json
//     * @return
//     */
//    public static IgnoreCaseMap getIgnoreCaseMapFromJson(String json) {
//        IgnoreCaseMap map = new IgnoreCaseMap();
//        if (json != null) {
//            Gson gson = new Gson();
//            try {
//                map = gson.fromJson(json, IgnoreCaseMap.class);
//            } catch (Exception e) {
//                ;
//            }
//            return map;
//        }
//        if (map == null) {
//            map = new IgnoreCaseMap();
//        }
//        return map;
//    }


    public static Map<String, Object> getMap(String json) {
        if (Strings.isNullOrEmpty(json)) {
            return null;
        }

        Gson gson = new GsonBuilder().
                registerTypeAdapter(Double.class, new JsonSerializer<Double>() {

                    @Override
                    public void serialize(Double aDouble, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {

                    }

                    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
                        if (src == src.longValue())
                            return new JsonPrimitive(src.longValue());
                        return new JsonPrimitive(src);
                    }
                }).create();


        return gson.fromJson(json, new TypeToken<HashMap<String, Object>>() {
        }.getType());
    }


    public static Map<String, String> getStringMap(String json) {
        if (Strings.isNullOrEmpty(json)) {
            return null;
        }

        final Gson gson = new Gson();
        final JsonReader jsonReader = new JsonReader(new CharArrayReader(json.toCharArray()));
        jsonReader.setLenient(true);

        return new Gson().fromJson(jsonReader, new TypeToken<HashMap<String, String>>() {
        }.getType());
    }

    public static List<Map<String, String>> getStringListMap(String json) {
        if (Strings.isNullOrEmpty(json)) {
            return null;
        }

        return new Gson().fromJson(json, new TypeToken<List<HashMap<String, String>>>() {
        }.getType());
    }


    /**
     * 通过Request 信息，获取JSON字符串格式(常规的POST,GET请求信息)
     * @param request
     * @return
     */
    public static String getJson(HttpServletRequest request ) {
        Map<String, String> map  = JsonUtils.getStringMap(request);
        String json = JsonUtils.getJson(map);
        return json;
    }


    /**
     * 从请求对象中提取参数到map
     *
     * @param request 请求对象
     * @return 参数map
     */
    public static Map<String, String> getStringMap(HttpServletRequest request) {

        Map<String, String[]> requestMap = request.getParameterMap();
        if (requestMap.isEmpty()) return null;

        Map<String, String> paramsMap = Maps.newHashMap();
        for (String key : requestMap.keySet()) {
            String[] valueArray = requestMap.get(key);
            String value = "";

            if (null != valueArray && 0 < valueArray.length) {
                value = valueArray[0];
            }

            if (!Strings.isNullOrEmpty(value)) {
                paramsMap.put(key, value);
            }
        }

        //log.info("参数--【" + paramsMap.toString() + "】");
        return paramsMap;
    }


//    /***
//     * @param dt 需要转化的DataTable
//     * @return Json字符串
//     */
//    public static String ToJson(DataTable dt) {
//        return ToJson(dt, new ArrayList<String>());
//    }
//
//    /***
//     * @param dt      需要转化的DataTable
//     * @param columns 需特定转换的列
//     * @return
//     */
//    public static String ToJson(DataTable dt, List<String> columns) {
//        if (dt.rows.length == 0) return "";
//
//        //判断是否传入特定的列
//        Boolean isHaveColumns = false;
//        if (columns.size() > 0) {
//            isHaveColumns = true;
//        }
//        StringBuilder sb = new StringBuilder();
//        sb.append("[");
//        for (int i = 0; i < dt.rows.length; i++) {
//            sb.append("{");
//            for (int j = 0; j < dt.rows[0].columns.length; j++) {
//                String key = dt.rows[0].columns[j].colName;
//
//                //判断是否传入特定的列
//                if (isHaveColumns) {
//                    //判断是否包含特定列
//                    if (columns.contains(key.toLowerCase())) {
//                        String value = dt.rows[i].getColumnValue(key);
//                        sb.append("\"" + key + "\":");
//                        if (j < dt.rows[0].columns.length - 1) {
//                            sb.append("\"" + value + "\",");
//                        } else {
//                            sb.append("\"" + value + "\"");
//                        }
//                    }
//                } else {
//                    String value = dt.rows[i].getColumnValue(key);
//                    sb.append("\"" + key + "\":");
//                    if (j < dt.rows[0].columns.length - 1) {
//                        sb.append("\"" + value + "\",");
//                    } else {
//                        sb.append("\"" + value + "\"");
//                    }
//                }
//            }
//            //sb.delete(sb.length() - 1, sb.length());
//            sb.append("},");
//        }
////        if (sb.length() > 3) {
////            sb.delete(sb.length() - 1, sb.length());
////        }
//
//        if (sb.toString().endsWith(",")) {
//            sb.delete(sb.length() - 1, sb.length());
//        }
//
//        sb.append("]");
//        String json = sb.toString();
//        json = json.replaceAll(",}", "}");
//        return json;
//    }
//
//    /***
//     * Json转DataTable
//     * @param json
//     * @return
//     */
//    public static  DataTable ToTable(String json) {
//        DataTable dt = new DataTable();
//        JsonParser parser = new JsonParser();
//        JsonElement el = parser.parse(json);
//        JsonArray jsonArray = el.getAsJsonArray();
//        for (int i = 0; i < jsonArray.size(); i++) {
//            JsonObject jo = jsonArray.get(i).getAsJsonObject();
//            Set<Map.Entry<String, JsonElement>> entrySet = jo.entrySet();
//            DataRow dtrow = new DataRow();
//            for (Map.Entry<String, JsonElement> entry : entrySet) {
//                dtrow.addColumn(new DataColumn(entry.getKey(), entry.getValue()));
//
//            }
//            dt.addRow(dtrow);
//        }
//        return dt;
//    }
//
//    /**
//     * 从request请求中流中，获取json字符串，并转换为特定对象（必须是按流的方式，提交的JSON才有效）
//     *
//     * @param request     请求对象
//     * @param entityClass 转换的对象类
//     * @return 转换之后的实体
//     */
//    public static <T> T createObjectFromJson(HttpServletRequest request, Class<T> entityClass) {
//        String requestContent = RequestUtils.getJsonDataFromRequest(request, "UTF-8");
//        return createObjectFromJson(requestContent, entityClass);
//    }

    /**
     * 把json字符串 转换为java对象，解决了多级的json转换为java对象失败的问题；
     * @param json
     * @param entityClass
     * @param <T>
     * @return
     */
    public static <T> T createObjectFromJson(String json, Class<T> entityClass) {
        try {

            final Gson gson = new Gson();
            final JsonReader jsonReader = new JsonReader(new CharArrayReader(json.toCharArray()));
            jsonReader.setLenient(true);
            return new Gson().fromJson(jsonReader, entityClass);
        } catch (JsonSyntaxException e) {
            e.printStackTrace();
        }
        return null;
    }



//    public static List<TestModel> parseNoHeaderJsonArray(String jsonStr)
//    {
//        JsonParser parser = new JsonParser();
//        JsonArray jsonArray = parser.parse(jsonStr).getAsJsonArray();
//        Gson gson = new Gson();
//        ArrayList<TestModel> models = Lists.newArrayList();
//        for (JsonElement domain:jsonArray) {
//            TestModel testModel = gson.fromJson(domain,TestModel.class);
//            models.add(testModel);
//        }
//        return models;
//    }



    public static JsonArray stringToJsonArr(String jsonStr)
    {
        Gson gson = new Gson();
        JsonParser parser = new JsonParser();
        JsonElement el = parser.parse(jsonStr);
        JsonArray jsonArray = el.getAsJsonArray();
        return jsonArray;
    }

//    public static String res2JsonStr(ResponseObject object)
//    {
//        StringBuffer buffer = new StringBuffer();
//        buffer.append("{\"code\":")
//                .append(object.getStatus())
//                .append(",");
//        buffer.append("\"message\":")
//                .append(object.getMessage())
//                .append(",");
//        PageResultModel domain = (PageResultModel) object.getResult();
//        buffer.append("\"result\":{")
//                .append("\"pageCount\":")
//                .append(domain.getPageCount())
//                .append(",");
//        buffer.append("\"pageNo\":")
//                .append(domain.getPageNo())
//                .append(",");
//        buffer.append("\"pageSize\":")
//                .append(domain.getPageSize())
//                .append(",");
//        buffer.append("\"rowCount\":")
//                .append(domain.getRowCount())
//                .append(",");
//        buffer.append("\"resultList\":");
//        if(((DataTable)domain.getResult()).rows.length >0)
//        {
//            buffer.append(ToJson((DataTable)domain.getResult()));
//        }
//        if(((DataTable)domain.getResult()).rows.length == 0)
//        {
//            buffer.append("\"\"");
//        }
//        buffer.append("}");
//        buffer.append("}");
//        return buffer.toString();
//    }

//    public static void main(String[] args) {
//        String jsonStr = "{\n" +
//                "    \"homeDeviceList\": [\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1737\",\n" +
//                "            \"homeNum\": \"101\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1736\",\n" +
//                "            \"homeNum\": \"102\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1735\",\n" +
//                "            \"homeNum\": \"103\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1734\",\n" +
//                "            \"homeNum\": \"104\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1733\",\n" +
//                "            \"homeNum\": \"105\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1732\",\n" +
//                "            \"homeNum\": \"106\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1729\",\n" +
//                "            \"homeNum\": \"201\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1728\",\n" +
//                "            \"homeNum\": \"202\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1727\",\n" +
//                "            \"homeNum\": \"203\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1726\",\n" +
//                "            \"homeNum\": \"204\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"deviceSeries\": \"\",\n" +
//                "            \"deviceTypeName\": \"门锁\",\n" +
//                "            \"homeDeviceID\": \"1725\",\n" +
//                "            \"homeNum\": \"205\",\n" +
//                "            \"state\": \"0\"\n" +
//                "        }\n" +
//                "    ],\n" +
//                "    \"imagePathList\": [\n" +
//                "        {\n" +
//                "            \"imagePath\": \"aaa\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"imagePath\": \"bbb\"\n" +
//                "        },\n" +
//                "        {\n" +
//                "            \"imagePath\": \"ccc\"\n" +
//                "        }\n" +
//                "    ],\n" +
//                "    \"orderId\": \"212\",\n" +
//                "    \"ticket\": \"QxidECG1AN9YovxO6I8PxJZ4R6AiRyi0v05TEZiU+4J9+XZFMpKpLvJeic9yMfSbcZIGBqsb2Xs=\"\n" +
//                "}";
////        Map<String,Object> map = JsonUtils.getMap(jsonStr);
////        List<TestModel> list = JsonUtils.parseNoHeaderJsonArray(map.get("homeDeviceList").toString());
////        for (TestModel domain:list) {
////            System.out.println(domain.toString());
////        }
////        GetWorkListResult getWorkListResult = new GsonBuilder().disableHtmlEscaping().create().fromJson(httpResult, GetWorkListResult.class);
////        TestModel2 testModel2 = new GsonBuilder().disableHtmlEscaping().create().fromJson(jsonStr, TestModel2.class);
////        System.out.println(testModel2.toString());
//    }
}
